package com.yunji.cabinet.device.impl;

import com.google.common.collect.Lists;
import com.yunji.cabinet.bo.CapacityQuantityBO;
import com.yunji.cabinet.cache.CabinetCache;
import com.yunji.cabinet.context.calculate.CabinetCalculate;
import com.yunji.cabinet.device.*;
import com.yunji.cabinet.device.factory.DeviceStrategyFactory;
import com.yunji.cabinet.domain.DeviceEventDO;
import com.yunji.cabinet.dto.device.DeviceCommandDTO;
import com.yunji.cabinet.dto.device.DeviceShoppingDTO;
import com.yunji.common.exception.device.DeviceErrorEnum;
import com.yunji.common.exception.device.DeviceException;
import com.yunji.common.model.cache.ContainerTypeCacheDTO;
import com.yunji.common.utils.JsonUtil;
import com.yunji.coffee.entity.bo.CommonDeviceInfoBO;
import com.yunji.coffee.entity.dto.WipeDeviceInfoDTO;
import com.yunji.order.dto.OrderOrdinalDTO;
import com.yunji.product.cache.ProductCache;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Component(DeviceStrategyFactory.WIPE)
public class WipeDeviceCommandEngine extends DeviceCommandEngine {

    @Override
    public String getTypeCode() {
        return ContainerTypeEnum.WIPE.getTypeCode();
    }

    @Override
    public Integer getRssi(String imei) {
        WipeDeviceInfoDTO newest = DeviceSpinService.getNewest(imei, getTypeCode());
        if (newest != null)
            return newest.getRssi();
        else
            throw new DeviceException(DeviceErrorEnum.CHECKED_202509, imei);
    }

    @Override
    public List<Integer> topInfraredTest(String imei) {
        ContainerTypeCacheDTO containerType = CabinetCache.getContainerType(getTypeCode());
        WipeDeviceInfoDTO newest = DeviceSpinService.getNewest(imei, getTypeCode());
        if (newest != null)
            return Lists.newArrayList(containerType.getTypeHeight().intValue() - newest.getDistance());
        else
            throw new DeviceException(DeviceErrorEnum.CHECKED_202506, imei);
    }

    @Override
    public CommonDeviceInfoBO getDeviceInfo(DeviceEventDO data) {
        return new CommonDeviceInfoBO(JsonUtil.readValue(data.getBeforeCmd(), WipeDeviceInfoDTO.class),
                JsonUtil.readValue(data.getAfterCmd(), WipeDeviceInfoDTO.class));
    }


    @Override
    public boolean tissueStatus(String imei, List<OrderOrdinalDTO> dtoList) {
        WipeDeviceInfoDTO info = (WipeDeviceInfoDTO) DeviceInfoCache.getInfo(imei);
        return info != null && info.getTissueStatus() == 1 && info.getSleepStatus() == 0;
    }

    @Override
    public List<OrderOrdinalDTO> getProductNums(String imei) {
        return new ArrayList<>();
    }

    @Override
    public Boolean shippingTest(String imei) {
        return DeviceCommandEngine.executeCommand(new DeviceCommandDTO(DeviceEventEnum.FACTORY_TEST.name(),
                DeviceCommandEnum.OPEN_SHIPPING.name(), imei, Lists.newArrayList(new DeviceShoppingDTO(1, 1))));
    }

    @Override
    public boolean isLock(String imei) {
        WipeDeviceInfoDTO info = (WipeDeviceInfoDTO) DeviceInfoCache.getInfo(imei);
        return info != null && info.getLockStatus() == 1 && info.getSleepStatus() == 0;
    }

    @Override
    public Integer getProductCeiling(String typeCode, Long productId) {
        ContainerTypeCacheDTO type = CabinetCache.getContainerType(typeCode);
        BigDecimal typeHeight = type.getTypeHeight();
        BigDecimal bottomHeight = ProductCache.getBottomHeight(productId);
        return CabinetCalculate.getQuantityByHeightDecimal(CapacityQuantityBO.builder().distance(typeHeight.subtract(bottomHeight).intValue()).productId(productId).build()).intValue();
    }
}
